home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Development Platforms / Apple II / Apple II Sample Code / APW.SC / SC01Shell / P.Shell / Shell.p
Encoding:
Text File  |  1990-06-24  |  16.3 KB  |  548 lines  |  [TEXT/pdos]

  1. {
  2. *   Standard Application Shell  - Pascal Version
  3. *   By: Apple II Developer Technical Support
  4. *
  5. *       v3.0    Luther
  6. }
  7.  
  8. {
  9. *    Copyright (c) Apple Computer, Inc. 1988-1990
  10. *               All Rights Reserved
  11. *
  12. *    Developer Technical Support Apple II Sample Code
  13. *
  14.  
  15. *   ------------------------------------------------------
  16. *
  17. *   This program and its derivatives are licensed only for
  18. *   use on Apple computers.
  19. *
  20. *   Works based on this program must contain and
  21. *   conspicuously display this notice.
  22. *
  23. *   This software is provided for your evaluation and to
  24. *   assist you in developing software for the Apple IIGS
  25. *   computer.
  26. *
  27. *   DISCLAIMER OF WARRANTY
  28. *
  29. *   THE SOFTWARE IS PROVIDED "AS IS" WITHOUT
  30. *   WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  31. *   WITH RESPECT TO ITS MERCHANTABILITY OR ITS FITNESS
  32. *   FOR ANY PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO
  33. *   THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
  34. *   YOU.  SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU (AND
  35. *   NOT APPLE OR AN APPLE AUTHORIZED REPRESENTATIVE)
  36. *   ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING,
  37. *   REPAIR OR CORRECTION.
  38. *
  39. *   Apple does not warrant that the functions
  40. *   contained in the Software will meet your requirements
  41. *   or that the operation of the Software will be
  42. *   uninterrupted or error free or that defects in the
  43. *   Software will be corrected.
  44. *
  45. *   SOME STATES DO NOT ALLOW THE EXCLUSION
  46. *   OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY
  47. *   NOT APPLY TO YOU.  THIS WARRANTY GIVES YOU SPECIFIC
  48. *   LEGAL RIGHTS AND YOU MAY ALSO HAVE OTHER RIGHTS
  49. *   WHICH VARY FROM STATE TO STATE.
  50. }
  51.  
  52.  
  53. program Shell;
  54.  
  55. uses
  56.     Types,
  57.     GSOS,
  58.     Locator,
  59.     ADB,
  60.     IntMath,
  61.     TextTool,
  62.     Memory,
  63.     SANE,
  64.     ACE,
  65.     Resources,
  66.     MiscTool,
  67.     Scheduler,
  68.     Loader,
  69.     Quickdraw,
  70.     QDAux,
  71.     Events,
  72.     Controls,
  73.     Windows,
  74.     Menus,
  75.     LineEdit,
  76.     Dialogs,
  77.     Sound,
  78.     NoteSyn,
  79.     NoteSeq,
  80.     MIDI,
  81.     StdFile,
  82.     Scrap,
  83.     Desk,
  84.     Lists,
  85.     Fonts,
  86.     Print,
  87.     TextEdit,
  88.     Video;
  89.  
  90. const
  91.     { menu item numbers for standard DA menu items }
  92.     UndoID      = 250;
  93.     CutID       = 251;
  94.     CopyID      = 252;
  95.     PasteID     = 253;
  96.     ClearID     = 254;
  97.     CloseID     = 255;
  98.  
  99.     { application menu item numbers }
  100.     AboutID         = $1101;    { 1st item of 1st menu of 1st menu bar }
  101.     QuitID          = $1202;    { 2nd item of 2nd menu of 1st menu bar }
  102.     
  103.     { application menu numbers }
  104.     AppleMenuID     = $1100;    { 1st menu of 1st menu bar }
  105.     FileMenuID      = $1200;    { 2nd menu of 1st menu bar }
  106.     EditMenuID      = $1300;    { 3rd menu of 1st menu bar }
  107.  
  108.     { resource ID numbers }
  109.     BaseResID       = $00000000;    { start of resource ID numbers }
  110.     MenuBarOneRID   = $00001000;    { resource ID of menu bar }
  111.  
  112.     MyTaskMask      = $001FFFFF;{ handle all events possible }
  113.         
  114. var
  115.     { Standard global variables here }
  116.     MyMemoryID      : integer;  { application's memory ID }
  117.     Done            : boolean;  { flag to show when to quit application }
  118.     ToolRecRef      : Ref;      { StartStopRecRef from StartUpTools }
  119.     WindowKind      : integer;  { type of top window from GetWKind call }
  120.     MenuHeight      : integer;  { stored height of menu bar }
  121.  
  122.     { The following is the record that is used by TaskMaster to return
  123.       events. It is similar to a regular event record, except that there are
  124.       additional fields at the end. The first additional field is used to
  125.       convey some TaskMaster specific data back to the application. The second
  126.       additional field is called the TaskMask and is used to tell TaskMaster
  127.       what situations to handle.  In this shell, we tell TaskMaster to handle
  128.       everything by setting all currently defined bits to 1 (MyTaskMask) in
  129.       the initApp procedure. }
  130.  
  131.     MyEvent         : wmTaskRec;
  132.  
  133.  
  134. {******************************************************************************
  135. *
  136. * errorCheck:   This procedure is declared forward. This lets you check for
  137. *               fatal errors and still shut down fairly cleanly from
  138. *               anywhere in your program.
  139. }
  140.  
  141. procedure errorCheck(where : Integer);
  142.     FORWARD;
  143.  
  144.  
  145. {******************************************************************************
  146. *
  147. * doQuit:       Set the Done flag to true. This tells the Event loop to exit.
  148. *
  149. * Inputs:       NONE
  150. * Outputs:      Done set to true
  151. * Calls:        NONE
  152. }
  153.  
  154. procedure doQuit;
  155.  
  156. begin
  157.     Done := true;
  158. end;
  159.  
  160.  
  161. {******************************************************************************
  162. *
  163. * doAbout:      Bring up an Alert Dialog box with our about message in it.
  164. *
  165. * Inputs:       NONE
  166. * Outputs:      NONE
  167. * Calls:        NONE
  168. }
  169.  
  170. procedure doAbout;
  171.  
  172. const
  173.     alertFlags  = 4;        { reference is a ResourceID }
  174.  
  175. var
  176.     buttonHit   : integer;      { button number clicked }
  177.  
  178. begin
  179.     buttonHit := AlertWindow(alertFlags,NIL,Pointer(BaseResID+1));
  180. end;
  181.  
  182.  
  183. {******************************************************************************
  184. *
  185. * doMenu:       This routine is called when TaskMaster returns a menu
  186. *               event. It takes the menu item that was hit and calls the
  187. *               proper routine, and then unhilites the menu when it is done.
  188. *
  189. * Inputs:       TaskData holds menu item selected.
  190. * Outputs:      NONE
  191. * Calls:        doAbout, doQuit
  192. }
  193.  
  194. procedure doMenu;
  195.     
  196. const
  197.     alertFlags  = 4;            { reference is a ResourceID }
  198. var
  199.     menuNum,                    { ID of menu from which selection was made }
  200.     itemNum     : integer;      { ID of selected menu item }
  201.     buttonHit   : integer;      { button number clicked }
  202.  
  203. begin
  204.     menuNum := HiWord(MyEvent.wmTaskData);  { get menu ID }
  205.     itemNum := LoWord(MyEvent.wmTaskData);  { and item ID from MyEvent}
  206.     
  207.     case itemNum of
  208.         AboutID : doAbout;  { show About alert }
  209.         QuitID  : doQuit;   { set Done flag }
  210.         UndoID  :;
  211.         CutID   :;
  212.         CopyID  :;
  213.         PasteID :;
  214.         ClearID :;
  215.         CloseID :;          { close taken care of by TaskMaster }
  216.         otherwise
  217.             buttonHit := AlertWindow(alertFlags,NIL,Pointer(BaseResID+2));
  218.     end;
  219.  
  220.     {   The routine has been called. Unhilite the menu and return to the
  221.         Main Event Loop. }
  222.  
  223.     HiLiteMenu(false,menuNum);
  224. end;
  225.  
  226.  
  227. {******************************************************************************
  228. *
  229. * doSysChange:  Called by testTopWindow when the active window
  230. *               has changed to or from a system window.
  231. *
  232. * Inputs:       Bit 15 of WindowKind is 0 if top window is an application
  233. *               window, 1 if top window is a system window.
  234. * Outputs:      NONE
  235. * Calls:        NONE
  236. }
  237.  
  238. procedure doSysChange;
  239.  
  240. begin
  241.     if WindowKind < 0   { if bit 15 of WindowKind = 1 }
  242.         then
  243.             begin
  244.                 { enable the edit menu items and the close item }
  245.                 EnableMItem(UndoID);
  246.                 EnableMItem(CutID);
  247.                 EnableMItem(CopyID);
  248.                 EnableMItem(PasteID);
  249.                 EnableMItem(ClearID);
  250.                 EnableMItem(CloseID);
  251.                 
  252.                 { if your edit menu has items that are selectable when a
  253.                   NDA is not the active window, remove the next two lines. }
  254.                 SetMenuFlag(enableMenu,EditMenuID);
  255.                 HiliteMenu(false, EditMenuID);
  256.             end
  257.         else
  258.             begin
  259.                 { disable the edit menu items and the close item }
  260.                 DisableMItem(UndoID);
  261.                 DisableMItem(CutID);                
  262.                 DisableMItem(CopyID);               
  263.                 DisableMItem(PasteID);              
  264.                 DisableMItem(ClearID);              
  265.                 DisableMItem(CloseID);
  266.                 
  267.                 { if your edit menu has items that are selectable when a
  268.                   NDA is not the active window, remove the next two lines. }
  269.                 SetMenuFlag(disableMenu,EditMenuID);
  270.                 HiliteMenu(false, EditMenuID);
  271.             end;
  272. end;
  273.  
  274.  
  275. {******************************************************************************
  276. *
  277. * testTopWindow:This routine is called on every time through the event loop.
  278. *               If the type to the top window has changed from application
  279. *               window to system window or back, this routine will call
  280. *               doSysChange.
  281. *
  282. * Inputs:       NONE
  283. * Outputs:      NONE
  284. * Calls:        doSysChange
  285. }
  286.  
  287. procedure testTopWindow;
  288.  
  289. var
  290.     tempWindowPtr   : WindowPtr;    { active window's grafPort }
  291.     tempWindowKind  : integer;  { active window's kind }
  292.  
  293. begin
  294.     tempWindowPtr := FrontWindow;   { get active window's grafPort }
  295.     
  296.     if tempWindowPtr <> NIL     { if there is an active window }
  297.         then tempWindowKind := GetWKind(tempWindowPtr) { get its kind }
  298.         else tempWindowKind := 0; { force to application window kind }
  299.         
  300.     if tempWindowKind <> WindowKind 
  301.         then                    { window kind has changed }
  302.             begin               { save the WindowKind and change the menus }
  303.                 WindowKind := tempWindowKind;
  304.                 doSysChange;
  305.             end;
  306. end;
  307.  
  308.  
  309. {******************************************************************************
  310. *
  311. * closeTools:   Shut down the tools I started.
  312. *
  313. * Inputs:       NONE
  314. * Outputs:      NONE
  315. * Calls:        NONE
  316. }
  317.  
  318. procedure closeTools;
  319.  
  320. begin
  321.     { shut down tools started by StartUpTools }
  322.     ShutDownTools(refIsHandle,ToolRecRef);
  323.     
  324.     { shut down Memory Manager and Tool Locator }
  325.     MMShutDown(MyMemoryID);
  326.     TLShutDown;
  327. end;
  328.  
  329.  
  330. {******************************************************************************
  331. *
  332. * closeApp:     Close down things. This disposes of all items and
  333. *               memory that we allocated. Usually undoes what was done
  334. *               in initApp.  We don't close our window since _WindShutDown
  335. *               does it for us.
  336. *
  337. * Inputs:       NONE
  338. * Outputs:      NONE
  339. * Calls:        NONE
  340. }
  341.  
  342. procedure closeApp;
  343.  
  344. begin
  345.     { do nothing in this shell }
  346. end;
  347.  
  348.  
  349. {******************************************************************************
  350. *
  351. * eventLoop:    The Event Loop. Handle things until user selects Quit.
  352. *
  353. * Inputs:       NONE
  354. * Outputs:      NONE
  355. * Calls:        testTopWindow, doMenu
  356. }
  357.  
  358. procedure eventLoop;
  359.  
  360. var
  361.     taskCode    : integer;      { code indicating action to be taken }
  362.  
  363. begin
  364.     repeat
  365.         testTopWindow;          { test top window to see if it is a NDA }
  366.         
  367.         taskCode := TaskMaster(EveryEvent,MyEvent);
  368.         case taskCode of        { handle the event for this taskcode }
  369.             {   With most of these events, we do nothing (in fact, most
  370.                 applications will never see some of these events). You
  371.                 should cut the labels for events your application does
  372.                 not use out of this case statement. Any of these events
  373.                 your application does use should call a procedure to handle
  374.                 the event.  }
  375.             nullEvt:;
  376.             mouseDownEvt:;
  377.             mouseUpEvt:;
  378.             keyDownEvt:;
  379.             autoKeyEvt:;
  380.             updateEvt:;
  381.             activateEvt:;
  382.             switchEvt:;
  383.             deskAccEvt:;
  384.             driverEvt:;
  385.             app1Evt:;
  386.             app2Evt:;
  387.             app3Evt:;
  388.             app4Evt:;
  389.             wInDesk:;
  390.             wInMenuBar,             { do "In system menu bar" events and }
  391.             wInSpecial: doMenu;     { "Item ID selected was 250-255" events }
  392.             wClickCalled:;
  393.             wInContent:;
  394.             wInDrag:;
  395.             wInGrow:;
  396.             wInGoAway:;
  397.             wInZoom:;
  398.             wInInfo:;
  399.             wInDeskItem:;
  400.             wInFrame:;
  401.             wInactMenu:;
  402.             wClosedNDA:;
  403.             wCalledSysEdit:;
  404.             wTrackZoom:;
  405.             wHitFrame:;
  406.             wInControl:;
  407.             wInControlMenu:;
  408.         end;
  409.     until Done;                     { Loop until "Quit" is selected }
  410. end;
  411.  
  412.  
  413. {******************************************************************************
  414. *
  415. * initApp:      Perform any application specific initialization. For this app,
  416. *               we initialize the Done to false, set WindowKind to an
  417. *               application window kind, initialize the TaskMask in the event
  418. *               record, and initialize all of the menus.
  419. *               .
  420. *               You might use this procedure to create windows,
  421. *               initialize variables and allocate memory needed for
  422. *               the entire program.
  423. *
  424. * Inputs:       NONE
  425. * Outputs:      NONE
  426. * Calls:        NONE
  427. }
  428.  
  429. procedure initApp;
  430.  
  431. begin
  432.     Done := false;              { we aren't done yet }
  433.     
  434.     WindowKind := 0;            { window kind  = application }
  435.     
  436.     { tell TaskMaster what events to handle }
  437.     MyEvent.wmTaskMask := MyTaskMask;
  438.     
  439.     { create default system menu bar from a resource
  440.       and make it the current menu bar }
  441.       
  442.     SetSysBar(NewMenuBar2(refIsResource,Ref(MenuBarOneRID),NIL));
  443.     SetMenuBar(NIL);
  444.     
  445.     RefreshDeskTop(NIL);        { redraw the desktop }
  446.     
  447.     InitCursor;                 { normal arrow cursor }
  448.     
  449.     FixAppleMenu(AppleMenuID);  { add NDAs to Apple menu }
  450.     MenuHeight := FixMenuBar;   { set menu bar height }
  451.     DrawMenuBar;                { draw the menu bar }
  452. end;
  453.  
  454.  
  455. {******************************************************************************
  456. *
  457. * errorCheck:   This routine is called by initTools to check for startup
  458. *               errors. An error message is shown and everything is
  459. *               shut down if any errors are detected.
  460. *
  461. * Inputs:       where = the reference number that tells you where in the
  462. *               initTools procedure the error happened.
  463. * Outputs:      NONE (program exits)
  464. * Calls:        closeTools
  465. }
  466.  
  467. procedure errorCheck(where : Integer);
  468.  
  469. var
  470.     theError    : integer;      { the tool error number }
  471.     errStr      : str255;       { string to display error message }
  472.     tempChar    : integer;      { temp to eat character returned }
  473.  
  474. begin
  475.     if _toolErr <> 0 { _toolErr is an external var }
  476.         then
  477.             begin
  478.                 theError := _toolErr;   { store the error number }
  479.                 
  480.                 { initialize errStr }
  481.                 errStr := 
  482.             'Fatal Error $xxxx has occurred at xxxx. Press any key to exit:';
  483.     
  484.                 { Stick error # into a string }
  485.                 Int2Hex(theError,Pointer(Ord4(@errStr)+14),4);
  486.  
  487.                 { Stick loc # into a string }
  488.                 Int2Hex(where,Pointer(Ord4(@errStr)+35),4);
  489.     
  490.                 GrafOff;                        { turn off super Hires }
  491.                 WriteLine(errStr);              { write errStr to text screen }
  492.                 SysBeep;                        { ring the bell }
  493.                 tempChar := ReadChar(noEcho);   { & wait for keypress }
  494.     
  495.                 closeTools;     { ShutDown my Tools }
  496.                 Halt;           { quit with APW status = 1 }
  497.                                 { Halt may be a compiler specific procedure }
  498.             end;
  499. end;
  500.  
  501.  
  502. {******************************************************************************
  503. *
  504. * initTools:    Load and startup the tools needed. errorCheck is called
  505. *               after each startup to check for errors.
  506. *
  507. * Inputs:       NONE
  508. * Outputs:      NONE
  509. * Calls:        errorCheck
  510. }
  511.  
  512. procedure initTools;
  513.  
  514. begin
  515.     TLStartUp;                  { start up Tool Locator }
  516.     errorCheck(1);              { Make sure all is OK }
  517.  
  518.     MyMemoryID := MMStartUp;    { start up Memory Manager & get Memory ID }
  519.     errorCheck(2);              { Make sure all is OK }
  520.     
  521.     { start up the rest of the tools }
  522.     ToolRecRef := StartUpTools(MyMemoryID,refIsResource,Ref(BaseResID+1));
  523.     errorCheck(3);              { Make sure all is OK }
  524. end;
  525.  
  526.  
  527. {******************************************************************************
  528. *
  529. * main:         This is the main routine. It calls procedures to startup
  530. *               the tools, initialize application specific data, run the
  531. *               main eventLoop, close the application, and shutdown the tools.
  532. *               
  533. * Inputs:       NONE
  534. * Outputs:      NONE
  535. * Calls:        initTools, initApp, eventLoop, closeApp, closeTools
  536. }
  537.  
  538. begin
  539.     initTools;              { Initialize tools. }
  540.     initApp;                { Initialize application specific stuff. }
  541.  
  542.     eventLoop;              { Do application stuff until user wants to
  543.                               do something else! }
  544.  
  545.     closeApp;               { ShutDown application specific things. }
  546.     closeTools;             { ShutDown the tools. }
  547. end.
  548.